home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xquinto / xquinto_x11.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  11.2 KB  |  478 lines

  1. /* xquinto.c: game, objective is to reverse color of all squares.
  2.    complie with: cc -o xquinto xquinto.c -lX11
  3. */
  4.    
  5.    
  6. #include <stdio.h>
  7. #include <sys/time.h>
  8. #include <signal.h>
  9. #include <time.h>
  10. /* #include "copyright.h" not supplied on net */
  11.  
  12. #define HEIGHT 20
  13. #define WIDTH 20
  14.  
  15. int myarr[HEIGHT][WIDTH];
  16. int height;
  17. int width;
  18. int showmove = 0;
  19. char colorname[4][64] =
  20. {
  21.     "notused","red","blue","yellow"
  22. };
  23.  
  24. char *getenv();
  25. void parseOptions();
  26. void extractOptions();
  27. void XStuff();
  28. void newscreen();
  29. void draw_screen();
  30. void getXevent();
  31. void CreatePixmaps();
  32. void getXevent();
  33. void DrawShadow();
  34. void keyboard();
  35. void redraw_array();
  36. void DrawCell();
  37.  
  38. void main(argc,argv)
  39.     int argc;
  40.     char *argv[];
  41. {
  42.     int i = 1;
  43.     int done = 0;
  44.  
  45.     height = 5;
  46.     width = 5;
  47.     while (i < argc && argv[i][0] == '-') {
  48.         if (strcmp(argv[i], "-height") == 0) {
  49.             height = atoi(argv[i+1]);
  50.             i++;
  51.         }
  52.         else if (strcmp(argv[i], "-width") == 0) {
  53.             width = atoi(argv[i+1]);
  54.             i++;
  55.         }
  56.         else if (strcmp(argv[i], "-square") == 0) {
  57.             width = atoi(argv[i+1]);
  58.             height = width;
  59.             i++;
  60.         }
  61.         else if (strcmp(argv[i], "-color1") == 0) {
  62.             sprintf(colorname[1], argv[i+1]);
  63.             i++;
  64.         }
  65.         else if (strcmp(argv[i], "-color2") == 0) {
  66.             sprintf(colorname[2], argv[i+1]);
  67.             i++;
  68.         }
  69.         else if (strcmp(argv[i], "-color3") == 0) {
  70.             sprintf(colorname[3], argv[i+1]);
  71.             i++;
  72.         }
  73.         i++;
  74.     }
  75.  
  76.     width = (width > WIDTH) ? WIDTH : width;
  77.     height = (height > HEIGHT) ? HEIGHT : height;
  78.  
  79.     parseOptions(argc,argv);
  80.     extractOptions();
  81.     XStuff(argc,argv);
  82.  
  83.     newscreen();
  84.     draw_screen();
  85.     while(!done) getXevent(); 
  86. }
  87.  
  88. int InArray(x,y)
  89. {
  90.     return ((x >= 0 && x < width) && (y >= 0 && y < height)) ? 1 : 0;
  91. }
  92.  
  93.  
  94. void MarkCell(x,y)
  95. {
  96.     if (InArray(x,y)) {
  97.         myarr[x][y] = 3 - myarr[x][y];
  98.         DrawCell(x,y);
  99.     }
  100.     if (InArray(x-1,y)) {
  101.         myarr[x-1][y] = (2 + myarr[x-1][y])%4;
  102.         DrawCell(x-1,y);
  103.     }
  104.     if (InArray(x+1,y)) {
  105.         myarr[x+1][y] = (2 + myarr[x+1][y])%4;
  106.         DrawCell(x+1,y);
  107.     }
  108.     if (InArray(x,y+1)) {
  109.         myarr[x][y+1] = (2 + myarr[x][y+1])%4;
  110.         DrawCell(x,y+1);
  111.     }
  112.     if (InArray(x,y-1)) {
  113.         myarr[x][y-1] = (2 + myarr[x][y-1])%4;
  114.         DrawCell(x,y-1);
  115.     }
  116. }
  117.  
  118. int ReadCell(x,y)
  119. {
  120.     return myarr[x][y];
  121. }
  122.  
  123. void newscreen()
  124. {
  125.     int i,j,k;
  126.  
  127.     for(i=0; i < width; i++)
  128.         for(j=0; j < height; j++)
  129.             myarr[i][j] = 0;
  130. }
  131.  
  132. /* X include files */
  133.  
  134. #include <X11/Xlib.h>
  135. #include <X11/Xutil.h>
  136. #include <X11/X.h>
  137. #include <X11/Xresource.h>
  138. #include <strings.h>
  139.  
  140. #include "gray.xbm"
  141. #include "white.xbm"
  142.  
  143.  
  144. Display *display;
  145. int screen;
  146. Window  window;
  147. GC gc;
  148. XSizeHints hint;
  149. Pixmap patpix[4];
  150.  
  151. Colormap cmap;
  152. unsigned long foreground, background;
  153. unsigned long getcolor();
  154. int depth;
  155. int mono = 0;
  156.  
  157. #define SWIDTH  40 /* cell   */
  158. #define SHEIGHT 40
  159. #define BWIDTH  14 /* border */
  160. #define BHEIGHT 14
  161.  
  162. int quit()
  163. {
  164.     exit(1);
  165. }
  166.  
  167. static XrmDatabase rDB;
  168. static XrmDatabase homeDB;
  169. static XrmDatabase commandlineDB;
  170.  
  171. void parseOptions(argc,argv)
  172.     int argc;
  173.     char *argv[];
  174. {
  175.     XrmValue value;
  176.     char *str_type[40];
  177.     char filename[1024];
  178.     char *sptr;
  179.     char DisplayName[256];
  180.     static int opTableEntries = 4;
  181.     static XrmOptionDescRec opTable[] =
  182.     {
  183.         {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL},
  184.         {"-geometry",  ".geometry", XrmoptionSepArg, (caddr_t) NULL},
  185.         {"-mono",  ".mono", XrmoptionIsArg, (caddr_t) NULL},
  186.         {"-showmove",  ".showmove", XrmoptionIsArg, (caddr_t) NULL}
  187.     };
  188.  
  189.     /* Get command line options */
  190.     XrmParseCommand(&commandlineDB, opTable, opTableEntries, "xquinto",
  191.         &argc, argv);
  192.  
  193.     DisplayName[0] = '\0';
  194.     if(XrmGetResource(commandlineDB, "xquinto.display",
  195.                       "Xquinto.Display", str_type, &value) == True)
  196.         strncpy(DisplayName,value.addr,(int) value.size);
  197.     if(!(display = XOpenDisplay(DisplayName))) {
  198.         fprintf(stderr,"Error: can't open display\n");
  199.         exit(1);
  200.     } 
  201.     screen = DefaultScreen(display);
  202.     depth = DefaultDepth(display,screen);
  203.     if(depth == 1) mono = 1;
  204.  
  205.     sptr = getenv("HOME");
  206.     strncpy(filename,sptr,sizeof(filename));
  207.     strncat(filename,"/.Xdefaults",sizeof(filename) - strlen(filename));
  208.     filename[sizeof(filename)-1] = '\0';
  209.     homeDB = XrmGetFileDatabase(filename);
  210.     XrmMergeDatabases(homeDB,&rDB);
  211.     XrmMergeDatabases(commandlineDB,&rDB);
  212.  
  213. }
  214.  
  215. void extractOptions()
  216. {
  217.     char *str_type[40];
  218.     char str[20];
  219.     XrmValue value;
  220.     int i;
  221.  
  222.     /* default program-specified window position and size */
  223.     hint.x = 20; hint.y = 30;
  224.     hint.width = width*SWIDTH + 2*BWIDTH;
  225.     hint.height = height*SHEIGHT + 2*BHEIGHT;
  226.  
  227.     if(XrmGetResource(rDB, "xquinto.mono",
  228.                       "Xquinto.mono", str_type, &value) == True)
  229.         mono = 1;
  230.  
  231.     if(XrmGetResource(rDB, "xquinto.showmove",
  232.                       "Xquinto.showmove", str_type, &value) == True)
  233.         showmove = 1;
  234.  
  235.     for(i=1; i < 4; i++) {
  236.         sprintf(str,"xquinto.color%1d",i);
  237.         if (XrmGetResource(rDB, str,
  238.             "Xquinto.Color", str_type, &value) == True) {
  239.             strncpy(colorname[i],value.addr,(int) value.size);
  240.             colorname[i][value.size] = '\0';
  241.         }
  242.     }
  243. }
  244.  
  245.  
  246. void XStuff(argc,argv)
  247.     int argc;
  248.     char *argv[];
  249. {
  250.  
  251.     /* default pixel values */
  252.     cmap = DefaultColormap(display,screen);
  253.     background = WhitePixel(display,screen);
  254.     foreground = BlackPixel(display,screen);
  255.  
  256.     /* window creation */
  257.     window = XCreateSimpleWindow (display,
  258.                 DefaultRootWindow(display),
  259.                 hint.x, hint.y, hint.width, hint.height,
  260.                 5, foreground, getcolor("gray", background));
  261.     XSetStandardProperties(display, window, argv[0], argv[0],
  262.                            None, argv, argc, &hint);
  263.  
  264.     /* GC creation and initialization */
  265.     gc = XCreateGC(display, window, 0, 0);
  266.     XSetBackground(display, gc, background);
  267.     XSetForeground(display, gc, foreground);
  268.  
  269.     /* input event selection */
  270.     XSelectInput(display, window,
  271.         Button1MotionMask | Button2MotionMask | Button3MotionMask |
  272.          ButtonPressMask | ButtonReleaseMask | 
  273.         KeyPressMask | ExposureMask);
  274.  
  275.     CreatePixmaps();
  276.  
  277.     /* window mapping */
  278.     XMapRaised(display, window);
  279.     XFlush(display);
  280. }
  281.  
  282.  
  283. void CreatePixmaps()
  284. {
  285.     char *pixstr = ".";
  286.     unsigned long patbg, patfg;
  287.  
  288.     if(!mono) patbg = getcolor(colorname[1] ,background); 
  289.     patpix[0] = XCreatePixmapFromBitmapData(display,window,
  290.                         gray_xbm_bits,SWIDTH,SHEIGHT,foreground,
  291.                         patbg, depth);
  292.     patpix[1] = XCreatePixmapFromBitmapData(display,window,
  293.                         gray_xbm_bits,SWIDTH,SHEIGHT,foreground,
  294.                         patbg, depth);
  295.     if(!mono) patbg = getcolor(colorname[2],background); 
  296.     patpix[2] = XCreatePixmapFromBitmapData(display,window,
  297.                         white_xbm_bits,SWIDTH,SHEIGHT,foreground,
  298.                         patbg, depth);
  299.     patpix[3] = XCreatePixmapFromBitmapData(display,window,
  300.                         white_xbm_bits,SWIDTH,SHEIGHT,foreground,
  301.                         patbg, depth);
  302.  
  303.     if(showmove) { /* show the '.' on clicked squares */
  304.         patfg = getcolor(colorname[3],foreground);  
  305.         XSetForeground(display, gc, patfg);
  306.         XDrawString(display,patpix[1],gc,SWIDTH/2-3,SHEIGHT/2,pixstr,1);
  307.         XDrawString(display,patpix[3],gc,SWIDTH/2-3,SHEIGHT/2,pixstr,1);
  308.         XSetForeground(display, gc, foreground);
  309.     }
  310. }
  311.  
  312.  
  313. unsigned long getcolor(s, monocolor)
  314.     char *s;
  315.     unsigned long monocolor;
  316. {
  317.     XColor exact_def;
  318.  
  319.     if(!mono) {
  320.         XParseColor(display,cmap,s,&exact_def);
  321.         XAllocColor(display,cmap,&exact_def);
  322.         return exact_def.pixel;
  323.     }
  324.     else return monocolor;
  325. }
  326.  
  327. void getXevent()
  328. {
  329.     char text[10];
  330.     static int x,y;
  331.     int newx,newy;
  332.     KeySym  key;
  333.     XEvent event;
  334.  
  335.     XNextEvent(display, &event);
  336.     switch(event.type)
  337.     {
  338.         case Expose:
  339.             if(event.xexpose.window == window)
  340.                 if(event.xexpose.count == 0)
  341.                     draw_screen();
  342.             break;
  343.         case KeyPress:
  344.             if(event.xkey.window == window) {
  345.                 XLookupString(&event, text, 1, &key, 0);
  346.                 keyboard(text[0]);
  347.                 text[0] = '0';
  348.             }
  349.             break;
  350.         case MotionNotify:
  351.             newx = (event.xmotion.x - BWIDTH)/SWIDTH;
  352.             newy = (event.xmotion.y - BHEIGHT)/SHEIGHT;
  353.             if(newx != x || newy != y) {
  354.                 x = newx; y = newy;
  355.             }
  356.             break;
  357.         case ButtonPress:
  358.             break;
  359.         case ButtonRelease:
  360.             if(event.xkey.window == window) {
  361.                 x = (event.xbutton.x - BWIDTH)/SWIDTH;
  362.                 y = (event.xbutton.y - BHEIGHT)/SHEIGHT;
  363.                 if(InArray(x,y)) MarkCell(x,y);
  364.             }
  365.             break;
  366.         default:
  367.             break;
  368.     }
  369. }
  370.  
  371.  
  372. void draw_screen()
  373. {
  374.     XClearWindow(display, window);
  375.     DrawShadow(0, 0, width*SWIDTH + 2*BWIDTH - 1, 
  376.                height*SHEIGHT + 2*BHEIGHT - 1, 3); 
  377.     DrawShadow(BWIDTH-4, BHEIGHT-4, BWIDTH + width*SWIDTH + 3,
  378.                BHEIGHT + height*SHEIGHT +3, -3); 
  379.     redraw_array();
  380. }
  381.  
  382. void DrawShadow(x1,y1,x2,y2,dir)
  383.     int x1;
  384.     int y1;
  385.     int x2;
  386.     int y2;
  387.     int dir;
  388. {
  389.     int i;
  390.     GC highlightgc,shadowgc;
  391.  
  392.     highlightgc = XCreateGC(display, window, 0, 0);
  393.     shadowgc = XCreateGC(display, window, 0, 0);
  394.  
  395.     if(dir < 0) {
  396.         XSetForeground(display, highlightgc, foreground);
  397.         XSetForeground(display, shadowgc, background);
  398.         dir = -dir;
  399.     }
  400.     else {
  401.         XSetForeground(display, shadowgc, foreground);
  402.         XSetForeground(display, highlightgc, background);
  403.     }
  404.  
  405.     for(i=0; i < dir; i++) {
  406.         XDrawLine(display,window,highlightgc,x1,y1,x1,y2);
  407.         XDrawLine(display,window,shadowgc,x1,y2,x2,y2);
  408.         XDrawLine(display,window,shadowgc,x2,y1,x2,y2);
  409.         XDrawLine(display,window,highlightgc,x1,y1,x2,y1);
  410.         x1++; x2--; y1++; y2--;
  411.     }
  412. }
  413.  
  414. void keyboard(c)
  415.     int c;
  416. {
  417.     switch(c){
  418.         case 'q':
  419.             quit();
  420.             break;
  421.         case 'w':
  422.             width--;
  423.             break; 
  424.         case 'W':
  425.             width++;
  426.             break; 
  427.         case 'h':
  428.             height--;
  429.             break; 
  430.         case 'H':
  431.             height++;
  432.             break; 
  433.         case 's':
  434.             width--;
  435.             height--;
  436.             break; 
  437.         case 'm':
  438.             width++;
  439.             height++;
  440.             break; 
  441.         case 'c':
  442.             break;
  443.         default:
  444.             return;
  445.     }
  446.     width = (width > WIDTH) ? WIDTH : width;
  447.     height = (height > HEIGHT) ? HEIGHT : height;
  448.     width = (width < 2) ? 2 : width;
  449.     height = (height < 2) ? 2: height;
  450.     newscreen();
  451.     draw_screen();
  452.  
  453.  
  454. }
  455.  
  456. void redraw_array()
  457. {
  458.     int i, j;
  459.  
  460.     for(i=0; i <height; i++)
  461.         for(j=0; j < width; j++) 
  462.             DrawCell(j,i); 
  463. }
  464.  
  465. void DrawCell(x,y)
  466.     int x;
  467.     int y;
  468. {
  469.     int val = ReadCell(x,y);
  470.  
  471.     if(InArray(x,y)) 
  472.         XCopyArea(display, patpix[val], window, gc, 0, 0, SWIDTH
  473.                   ,SHEIGHT, x*SWIDTH + BWIDTH, y*SHEIGHT + BHEIGHT);
  474. }
  475.  
  476.  
  477.  
  478.